package com.hudson.codec.domain;

import com.hudson.codec.hudson.utils.CodecUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

import java.util.Arrays;

public class MessageExtBrokerInner {

    private String topic;              // 消息主题
    private int queueId;               // 队列 ID
    private String tags;
    private long queueOffset;        // 消息在队列中的偏移量
    private long commitLogOffset;    // 消息在CommitLog中的偏移量
    private long bornTimestamp;      // 消息创建时间
    private long storeTimestamp;     // 消息存储时间
    private int retryNum;       // 消息消费重试次数
    private byte[] body;             // 消息体

    public MessageExtBrokerInner(String topic, int queueId,String tags, long queueOffset, long commitLogOffset, long bornTimestamp, long storeTimestamp, int retryNum, byte[] body) {
        this.topic = topic;
        this.queueId = queueId;
        this.tags = tags;
        this.queueOffset = queueOffset;
        this.commitLogOffset = commitLogOffset;
        this.bornTimestamp = bornTimestamp;
        this.storeTimestamp = storeTimestamp;
        this.retryNum = retryNum;
        this.body = body;
    }

    public MessageExtBrokerInner() {
    }

    public static Builder builder() {
        return new Builder();
    }

    // Builder 静态内部类
    public static class Builder {
        private String topic;              // 消息主题
        private int queueId;               // 队列 ID
        private String tags;
        private long queueOffset;
        private long commitLogOffset;
        private long bornTimestamp;
        private long storeTimestamp;
        private int retryNum;
        private byte[] body;

        public Builder topic(String topic) {
            this.topic = topic;
            return this;
        }

        public Builder queueId(int queueId) {
            this.queueId = queueId;
            return this;
        }

        public Builder tag(String tags) {
            this.tags = tags;
            return this;
        }

        public Builder queueOffset(long queueOffset) {
            this.queueOffset = queueOffset;
            return this;
        }

        public Builder commitLogOffset(long commitLogOffset) {
            this.commitLogOffset = commitLogOffset;
            return this;
        }

        public Builder bornTimestamp(long bornTimestamp) {
            this.bornTimestamp = bornTimestamp;
            return this;
        }

        public Builder storeTimestamp(long storeTimestamp) {
            this.storeTimestamp = storeTimestamp;
            return this;
        }

        public Builder body(byte[] body) {
            this.body = body;
            return this;
        }

        public Builder retryNum(int retryNum) {
            this.retryNum = retryNum;
            return this;
        }

        public MessageExtBrokerInner build() {
            return new MessageExtBrokerInner(topic, queueId,tags, queueOffset, commitLogOffset, bornTimestamp, storeTimestamp, retryNum, body);
        }
    }

    public String getTopic() {
        return topic;
    }

    public void setTopic(String topic) {
        this.topic = topic;
    }

    public int getQueueId() {
        return queueId;
    }

    public void setQueueId(int queueId) {
        this.queueId = queueId;
    }

    public long getQueueOffset() {
        return queueOffset;
    }

    public void setQueueOffset(long queueOffset) {
        this.queueOffset = queueOffset;
    }

    public long getCommitLogOffset() {
        return commitLogOffset;
    }

    public void setCommitLogOffset(long commitLogOffset) {
        this.commitLogOffset = commitLogOffset;
    }

    public long getBornTimestamp() {
        return bornTimestamp;
    }

    public void setBornTimestamp(long bornTimestamp) {
        this.bornTimestamp = bornTimestamp;
    }

    public long getStoreTimestamp() {
        return storeTimestamp;
    }

    public void setStoreTimestamp(long storeTimestamp) {
        this.storeTimestamp = storeTimestamp;
    }

    public int getRetryNum() {
        return retryNum;
    }

    public void setRetryNum(int retryNum) {
        this.retryNum = retryNum;
    }

    public byte[] getBody() {
        return body;
    }

    public void setBody(byte[] body) {
        this.body = body;
    }

    public String getTags() {
        return tags;
    }

    public void setTags(String tags) {
        this.tags = tags;
    }

    @Override
    public String toString() {
        return "MessageExtBrokerInner{" +
                "queueOffset=" + queueOffset +
                ", commitLogOffset=" + commitLogOffset +
                ", bornTimestamp=" + bornTimestamp +
                ", storeTimestamp=" + storeTimestamp +
                ", body=" + Arrays.toString(body) +
                '}';
    }

    /**
     * 从byte[]反序列化MessageExtBrokerInner
     */
    public static MessageExtBrokerInner deserialize(byte[] data) {
        if (data == null || data.length == 0) {
            return new MessageExtBrokerInner();
        }

        ByteBuf byteBuf = Unpooled.wrappedBuffer(data);
        try {
            return deserialize(byteBuf);
        } finally {
            // Unpooled.wrappedBuffer创建的ByteBuf不需要释放
            // byteBuf.release(); // 注意：wrappedBuffer不需要手动释放
        }
    }

    /**
     * 序列化MessageExtBrokerInner到byte[]
     */
    public static byte[] serialize(MessageExtBrokerInner message) {
        if (message == null) {
            return new byte[0];
        }

        // 不提前计算长度，使用默认大小的ByteBuf
        ByteBuf byteBuf = Unpooled.buffer(); // 使用默认初始容量

        try {
            serialize(message, byteBuf);
            byte[] result = new byte[byteBuf.readableBytes()];
            byteBuf.readBytes(result);
            return result;
        } finally {
            if (byteBuf.refCnt() > 0) {
                byteBuf.release();
            }
        }
    }

    /**
     * 序列化MessageExtBrokerInner到ByteBuf
     */
    public static void serialize(MessageExtBrokerInner message, ByteBuf out) {
        //topic
        CodecUtil.writeString(out,message.topic);

        //队列ID
        out.writeInt(message.queueId);

        //tags
        CodecUtil.writeString(out,message.tags);

        // 序列化消息在队列中的偏移量
        out.writeLong(message.queueOffset);

        // 序列化消息在CommitLog中的偏移量
        out.writeLong(message.commitLogOffset);

        // 序列化消息创建时间
        out.writeLong(message.bornTimestamp);

        // 序列化消息存储时间
        out.writeLong(message.storeTimestamp);

        // 消息重试次数
        out.writeInt(message.retryNum);

        // 序列化消息体
        byte[] body = message.body;
        if (body == null) {
            out.writeInt(0);
        } else {
            out.writeInt(body.length);
            out.writeBytes(body);
        }
    }


    /**
     * 从ByteBuf反序列化MessageExtBrokerInner
     */
    public static MessageExtBrokerInner deserialize(ByteBuf in) {
        MessageExtBrokerInner message = new MessageExtBrokerInner();

        //topic
        message.setTopic(CodecUtil.readString(in));

        //队列ID
        message.setQueueId(in.readInt());

        //tags
        message.setTopic(CodecUtil.readString(in));

        // 反序列化消息在队列中的偏移量
        message.setQueueOffset(in.readLong());

        // 反序列化消息在CommitLog中的偏移量
        message.setCommitLogOffset(in.readLong());

        // 反序列化消息创建时间
        message.setBornTimestamp(in.readLong());

        // 反序列化消息存储时间
        message.setStoreTimestamp(in.readLong());

        // 消息重试次数
        message.setRetryNum(in.readInt());

        // 反序列化消息体
        int bodyLength = in.readInt();
        if (bodyLength > 0) {
            byte[] body = new byte[bodyLength];
            in.readBytes(body);
            message.setBody(body);
        }

        return message;
    }
}


